﻿///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2023, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область СлужебныйПрограммныйИнтерфейс

#Область ОбработчикиСлужебныхСобытий

#Область СтандартныеПодсистемы

#Область БазоваяФункциональность

// См. ОбщегоНазначенияПереопределяемый.ПриДобавленииИсключенийПоискаСсылок.
Процедура ПриДобавленииИсключенийПоискаСсылок(ИсключенияПоискаСсылок) Экспорт
	
	ИсключенияПоискаСсылок.Добавить(
		Метаданные.РегистрыСведений.ИспользованиеПоставляемыхДополнительныхОтчетовИОбработокВОбластяхДанных.ПолноеИмя());
	
КонецПроцедуры

#КонецОбласти

#Область ДополнительныеОтчетыИОбработки

// Вызывается при определении наличия у текущего пользователя права на добавление дополнительного
// отчета или обработки в область данных.
//
// Параметры:
//  ДополнительнаяОбработка - СправочникОбъект.ДополнительныеОтчетыИОбработки, элемент справочника,
//    который записывается пользователем.
//  Результат - Булево - в этот параметр в данной процедуре устанавливается флаг наличия права,
//  СтандартнаяОбработка - Булево - в этот параметр в данной процедуре устанавливается флаг выполнения
//    стандартной обработки проверки права.
//
Процедура ПриПроверкеПраваДобавления(Знач ДополнительнаяОбработка, Результат, СтандартнаяОбработка) Экспорт
	
	Если Не ОбщегоНазначения.РазделениеВключено() Тогда
		Возврат;
	КонецЕсли;
		
	Если ПолучитьФункциональнуюОпцию("НезависимоеИспользованиеДополнительныхОтчетовИОбработокВМоделиСервиса") Тогда
		Возврат;
	КонецЕсли;
			
	СтандартнаяОбработка = Ложь;
	Если ДополнительнаяОбработка = Неопределено Тогда
		Результат = Ложь;
		Возврат;
	КонецЕсли;
		
	Если ДополнительнаяОбработка.ЭтоНовый() Тогда
		СсылкаОбработки = ДополнительнаяОбработка.ПолучитьСсылкуНового();
	Иначе
		СсылкаОбработки = ДополнительнаяОбработка.Ссылка;
	КонецЕсли;
	Результат = ЭтоПоставляемаяОбработка(СсылкаОбработки);
	
КонецПроцедуры

// Вызывается при проверке возможности загрузки дополнительного отчета или обработки из файла.
//
// Параметры:
//  ДополнительнаяОбработка - СправочникСсылка.ДополнительныеОтчетыИОбработки,
//  Результат - Булево - в этот параметр в данной процедуре устанавливается флаг наличия возможности
//    загрузки дополнительного отчета или обработки из файла,
//  СтандартнаяОбработка - Булево - в этот параметр в данной процедуре устанавливается флаг выполнения
//    стандартной обработки проверки возможности загрузки дополнительного отчета или обработки из файла.
//
Процедура ПриПроверкеВозможностиЗагрузкиОбработкиИзФайла(Знач ДополнительнаяОбработка, Результат, СтандартнаяОбработка) Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	
	Если ОбщегоНазначения.РазделениеВключено() Тогда
		
		Результат = (ПолучитьФункциональнуюОпцию("НезависимоеИспользованиеДополнительныхОтчетовИОбработокВМоделиСервиса")) 
			И (Не ЭтоПоставляемаяОбработка(ДополнительнаяОбработка));
		СтандартнаяОбработка = Ложь;
		
	КонецЕсли;
	
КонецПроцедуры

// Вызывается при проверке возможности выгрузки дополнительного отчета или обработки в файл.
//
// Параметры:
//  ДополнительнаяОбработка - СправочникСсылка.ДополнительныеОтчетыИОбработки,
//  Результат - Булево - в этот параметр в данной процедуре устанавливается флаг наличия возможности
//    выгрузки дополнительного отчета или обработки в файл,
//  СтандартнаяОбработка - Булево - в этот параметр в данной процедуре устанавливается флаг выполнения
//    стандартной обработки проверки возможности выгрузки дополнительного отчета или обработки в файл.
//
Процедура ПриПроверкеВозможностиВыгрузкиОбработкиВФайл(Знач ДополнительнаяОбработка, Результат, СтандартнаяОбработка) Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	
	Если ОбщегоНазначения.РазделениеВключено() Тогда
		
		Результат = Не ЭтоПоставляемаяОбработка(ДополнительнаяОбработка);
		СтандартнаяОбработка = Ложь;
		
	КонецЕсли;
	
КонецПроцедуры

// Заполняет виды публикации дополнительных отчетов и обработок, недоступные для использования
// в текущей модели информационной базы.
//
// Параметры:
//  НедоступныеВидыПубликации - Массив из Строка
//
Процедура ПриЗаполненииНедоступныхВидовПубликации(Знач НедоступныеВидыПубликации) Экспорт
	
	Если ОбщегоНазначения.РазделениеВключено() Тогда
		НедоступныеВидыПубликации.Добавить("РежимОтладки");
	КонецЕсли;
	
КонецПроцедуры

// Процедура должна вызываться из события ПередЗаписью справочника
//  ДополнительныеОтчетыИОбработки, выполняет проверку правомерности изменения реквизитов
//  элементов данного справочника для дополнительных обработок, полученных из
//  каталога дополнительных обработок менеджера сервиса.
//
// Параметры:
//  Источник - СправочникОбъект.ДополнительныеОтчетыИОбработки
//  Отказ - Булево - флаг отказа от выполнения записи элемента справочника.
//
Процедура ПередЗаписьюДополнительнойОбработки(Источник, Отказ) Экспорт
	
	Если Источник.ЭтоНовый() Тогда
		Возврат;
	КонецЕсли;
	
	Если Не ОбщегоНазначения.РазделениеВключено() Тогда
		Возврат;
	КонецЕсли;
	
	МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");
	Если МодульРаботаВМоделиСервиса.СеансЗапущенБезРазделителей() Тогда
		Возврат;
	КонецЕсли;
	
	Если ЭтоПоставляемаяОбработка(Источник.Ссылка) Тогда
		
		КонтролируемыеРеквизиты = ДополнительныеОтчетыИОбработкиВМоделиСервисаПовтИсп.КонтролируемыеРеквизиты();
		СтарыеЗначения = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Источник.Ссылка, КонтролируемыеРеквизиты);
		
		Для Каждого КонтролируемыйРеквизит Из КонтролируемыеРеквизиты Цикл
			
			ИсходныйРеквизит = Неопределено;
			РезультирующийРеквизит = Неопределено;
			
			Если ТипЗнч(Источник[КонтролируемыйРеквизит]) = Тип("ХранилищеЗначения") Тогда
				ИсходныйРеквизит = Источник[КонтролируемыйРеквизит].Получить();
			Иначе
				ИсходныйРеквизит = Источник[КонтролируемыйРеквизит];
			КонецЕсли;
			
			Если ТипЗнч(СтарыеЗначения[КонтролируемыйРеквизит]) = Тип("ХранилищеЗначения") Тогда
				РезультирующийРеквизит = СтарыеЗначения[КонтролируемыйРеквизит].Получить();
			Иначе
				РезультирующийРеквизит = СтарыеЗначения[КонтролируемыйРеквизит];
			КонецЕсли;
			
			Если ИсходныйРеквизит <> РезультирующийРеквизит Тогда
				ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru = 'Недопустимая попытка изменения значения реквизита %1 для дополнительной обработки %2, 
						|полученной из каталога дополнительных обработок менеджера сервиса.'"), 
					КонтролируемыйРеквизит, Источник.Наименование);
				
			КонецЕсли;
		КонецЦикла;
		
	КонецЕсли;
	
КонецПроцедуры

// Процедура должна вызываться из события ПередУдалением справочника
//  ДополнительныеОтчетыИОбработки.
//
// Параметры:
//  Источник - СправочникОбъект.ДополнительныеОтчетыИОбработки
//  Отказ - Булево - флаг отказа от выполнения удаления элемента справочника из информационной базы.
//
Процедура ПередУдалениемДополнительнойОбработки(Источник, Отказ) Экспорт
	
	Если Не ОбщегоНазначения.РазделениеВключено() Тогда
		Возврат;
	КонецЕсли;
	
	// Определим поставляемую обработку
	ПоставляемаяОбработка = ПоставляемаяОбработка(Источник.Ссылка);
	Если ЗначениеЗаполнено(ПоставляемаяОбработка) Тогда
		
		// Очистим сопоставление используемой обработки с поставляемой
		НаборЗаписей = РегистрыСведений.ИспользованиеПоставляемыхДополнительныхОтчетовИОбработокВОбластяхДанных.СоздатьНаборЗаписей();
		НаборЗаписей.Отбор.ПоставляемаяОбработка.Установить(ПоставляемаяОбработка);
		НаборЗаписей.Записать();
		
	КонецЕсли;
		
КонецПроцедуры

// Вызывается при получении регистрационных данных для нового дополнительного отчета или обработки.
//
Процедура ПриПолученииРегистрационныхДанных(Объект, РегистрационныеДанные, СтандартнаяОбработка) Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	Если Не Объект.ЭтоНовый() И ОбщегоНазначения.РазделениеВключено() Тогда
		ПоставляемаяОбработка = ПоставляемаяОбработка(Объект.Ссылка);
		Если ЗначениеЗаполнено(ПоставляемаяОбработка) Тогда
			ОбщегоНазначенияКлиентСервер.ДополнитьСтруктуру(РегистрационныеДанные, 
				ПолучитьРегистрационныеДанные(ПоставляемаяОбработка), Истина);
			СтандартнаяОбработка = Ложь;
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

// Вызывается при подключении внешней обработки.
//
// Параметры:
//  Ссылка - СправочникСсылка.ДополнительныеОтчетыИОбработки,
//  СтандартнаяОбработка - Булево - флаг необходимости выполнения стандартной обработки подключения
//    внешней обработки,
//  Результат - Строка - имя подключенного внешнего отчета или обработки (в том случае, если в обработчике
//    для параметра СтандартнаяОбработка было установлено значение Ложь).
//
Процедура ПриПодключенииВнешнейОбработки(Знач Ссылка, СтандартнаяОбработка, Результат) Экспорт
	
	Если Не ОбщегоНазначения.РазделениеВключено() Тогда
		Возврат;
	КонецЕсли;
	
	УстановитьПривилегированныйРежим(Истина);
	
	Если ТипЗнч(Ссылка) <> Тип("СправочникСсылка.ДополнительныеОтчетыИОбработки")
		Или Ссылка = Справочники.ДополнительныеОтчетыИОбработки.ПустаяСсылка() Тогда
		ВызватьИсключение НСтр("ru = 'Запрошено подключение несуществующей дополнительной обработки.'");
	КонецЕсли;
	
	ПроверитьВозможностьВыполнения(Ссылка);
	
	Если НЕ ЭтоПоставляемаяОбработка(Ссылка) 
		И ПолучитьФункциональнуюОпцию("НезависимоеИспользованиеДополнительныхОтчетовИОбработокВМоделиСервиса") Тогда
		Возврат;
	КонецЕсли;
	
	СтандартнаяОбработка = Ложь;
	ИспользуютсяПрофилиБезопасности = Ложь;
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ПрофилиБезопасности") Тогда
		МодульРаботаВБезопасномРежиме = ОбщегоНазначения.ОбщийМодуль("РаботаВБезопасномРежиме");
		ИспользуютсяПрофилиБезопасности = МодульРаботаВБезопасномРежиме.ИспользуютсяПрофилиБезопасности();
	КонецЕсли;
	
	Если ИспользуютсяПрофилиБезопасности Тогда

		ПараметрыПодключения = ПараметрыПодключенияИспользуемойОбработки(Ссылка);
		МодульРаботаВБезопасномРежимеВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВБезопасномРежимеВМоделиСервиса");
		БезопасныйРежим = МодульРаботаВБезопасномРежимеВМоделиСервиса.РежимИсполненияВнешнегоМодуля(Ссылка);
		Если БезопасныйРежим = Неопределено Тогда
			БезопасныйРежим = Истина;
		КонецЕсли;
		
	Иначе
		
		ПараметрыПодключения = ПараметрыПодключенияИспользуемойОбработки(Ссылка);
		БезопасныйРежим = ПараметрыПодключения.БезопасныйРежим;
		
		Если БезопасныйРежим Тогда
			
			ЗапросРазрешений = Новый Запрос(
			"ВЫБРАТЬ ПЕРВЫЕ 1
			|	ДополнительныеОтчетыИОбработкиРазрешения.НомерСтроки,
			|	ДополнительныеОтчетыИОбработкиРазрешения.ВидРазрешения
			|ИЗ
			|	Справочник.ДополнительныеОтчетыИОбработки.Разрешения КАК ДополнительныеОтчетыИОбработкиРазрешения
			|ГДЕ
			|	ДополнительныеОтчетыИОбработкиРазрешения.Ссылка = &Ссылка");
			
			ЗапросРазрешений.УстановитьПараметр("Ссылка", Ссылка);
			ЕстьРазрешения = Не ЗапросРазрешений.Выполнить().Пустой();
			РежимСовместимости = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, "РежимСовместимостиРазрешений");
			Если РежимСовместимости = Перечисления.РежимыСовместимостиРазрешенийДополнительныхОтчетовИОбработок.Версия_2_2_2 И ЕстьРазрешения Тогда
				БезопасныйРежим = Ложь;
			КонецЕсли;
			
		КонецЕсли;
		
	КонецЕсли;
	
	Если Константы.ИспользоватьПрофилиБезопасностиДляДОО.Получить() И НЕ БезопасныйРежим Тогда
		БезопасныйРежим = Строка(ПараметрыПодключения.ВерсияGUID);
	КонецЕсли;
	
	// АПК:552-выкл Подключение в области данных дополнительных отчетов и обработок, одобренных администратором сервиса.
	// АПК:556-выкл
	// АПК:553-выкл
	АдресВоВременномХранилище = ПоместитьВоВременноеХранилище(ПараметрыПодключения.ХранилищеОбработки.Получить());
	Менеджер = ?(ЭтоОтчет(Ссылка), ВнешниеОтчеты, ВнешниеОбработки);
	Результат = Менеджер.Подключить(АдресВоВременномХранилище, ПараметрыПодключения.ИмяОбъекта, БезопасныйРежим, 
		ОбщегоНазначения.ОписаниеЗащитыБезПредупреждений()); 
	// АПК:553-вкл
	// АПК:556-вкл
	// АПК:552-вкл
	
КонецПроцедуры

// Вызывается при создании объекта внешней обработки.
//
// Параметры:
//  Ссылка - СправочникСсылка.ДополнительныеОтчетыИОбработки - дополнительный отчет или обработка.
//  СтандартнаяОбработка - Булево - флаг необходимости выполнения стандартной обработки подключения
//                                  внешней обработки.
//  Результат - ВнешняяОбработка
//            - ВнешнийОтчет - объект подключенного внешнего отчета или обработки
//              (в том случае, если в обработчике для параметра СтандартнаяОбработка было установлено значение Ложь).
//
Процедура ПриСозданииВнешнейОбработки(Знач Ссылка, СтандартнаяОбработка, Результат) Экспорт
	
	СтандартнаяОбработка = Истина;
	ИмяОбработки = Неопределено;
	
	ПриПодключенииВнешнейОбработки(Ссылка, СтандартнаяОбработка, ИмяОбработки);
	
	Если СтандартнаяОбработка Тогда
		Возврат;
	КонецЕсли;
		
	Если ИмяОбработки = Неопределено Тогда
		ВызватьИсключение НСтр("ru = 'Запрошено создание объекта несуществующей дополнительной обработки.'");
	КонецЕсли;
	
	ПроверитьВозможностьВыполнения(Ссылка);
	
	// АПК:552-выкл Создание в области данных дополнительных отчетов и обработок, одобренных администратором сервиса.
	// АПК:553-выкл
	Если ЭтоОтчет(Ссылка) Тогда
		Результат = ВнешниеОтчеты.Создать(ИмяОбработки);
	Иначе
		Результат = ВнешниеОбработки.Создать(ИмяОбработки);
	КонецЕсли;
	// АПК:553-вкл
	// АПК:552-вкл
	
КонецПроцедуры

// Вызывается перед записью изменений регламентного задания дополнительных отчетов и обработок в модели сервиса.
//
// Параметры:
//   Объект - СправочникОбъект.ДополнительныеОтчетыИОбработки - объект дополнительного отчета или обработки.
//   Команда - СправочникТабличнаяЧастьСтрока.ДополнительныеОтчетыИОбработки.Команды - описание команды.
//   Задание - РегламентноеЗадание
//           - СтрокаТаблицыЗначений - описание регламентного задания.
//       См. РегламентныеЗаданияСервер.Задание.
//   Изменения - Структура - значения реквизитов задания, которые необходимо изменить.
//       См. описание 2-го параметра процедуры РегламентныеЗаданияСервер.ИзменитьЗадание.
//       Если установить Неопределено, то регламентное задание не будет изменено.
//
Процедура ПередОбновлениемЗадания(Объект, Команда, Задание, Изменения) Экспорт
	
	Если Не ОбщегоНазначения.РазделениеВключено() Тогда
		Возврат;
	КонецЕсли;
	
	Если Не Константы.РазрешитьВыполнениеДООРегламентнымиЗаданиямиВМоделиСервиса.Получить() Тогда
		ВызватьИсключение НСтр("ru = 'Периодическое выполнение команд дополнительных обработок в качестве заданий запрещено администратором сервиса.'");
	КонецЕсли;
	
	МинимальныйИнтервал = Константы.МинимальныйИнтервалРегламентныхЗаданийДОИОВМоделиСервиса.Получить();
	ИсходнаяДата = ТекущаяДатаСеанса();
	ПроверяемаяДата = ИсходнаяДата + МинимальныйИнтервал - 1;
	
	Если Задание.Расписание.ТребуетсяВыполнение(ПроверяемаяДата, ИсходнаяДата) Тогда
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Расписание, задаваемое для выполнения команд дополнительного отчета или обработки в качестве заданий, должно быть не чаще, чем 1 раз в %1 секунд.'"), 
			МинимальныйИнтервал);
	КонецЕсли;
		
КонецПроцедуры

#КонецОбласти

#Область ОбновлениеИнформационнойБазы

// См. ОбновлениеИнформационнойБазыБСП.ПриДобавленииОбработчиковОбновления.
Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт
	
	Если Не ОбщегоНазначения.РазделениеВключено() Тогда
		Возврат;
	КонецЕсли;
	
	Обработчик = Обработчики.Добавить();
	Обработчик.Версия = "*";
	Обработчик.Процедура = "ДополнительныеОтчетыИОбработкиВМоделиСервиса.ЗаблокироватьДополнительныеОтчетыИОбработкиДляОбновления";
	Обработчик.ОбщиеДанные = Истина;
	Обработчик.МонопольныйРежим = Ложь;
	
КонецПроцедуры

#КонецОбласти

#Область РаботаВМоделиСервиса

// Проверяет, является ли переданная дополнительная обработка экземпляром
// поставляемой дополнительной обработки.
//
// Параметры:
//   ИспользуемаяОбработка - СправочникСсылка.ДополнительныеОтчетыИОбработки - дополнительная обработка.
//
// Возвращаемое значение:
//  Булево
//
Функция ЭтоПоставляемаяОбработка(ИспользуемаяОбработка) Экспорт
	
	ПоставляемаяОбработка = ПоставляемаяОбработка(ИспользуемаяОбработка);
	Возврат ЗначениеЗаполнено(ПоставляемаяОбработка);
	
КонецФункции

// АПК:134-выкл для обратной совместимости.

// Выполняет установку поставляемой дополнительной обработки в текущую область данных после получения поставляемых данных
// и извещает менеджер сервиса в случае неудачи.
//
// Параметры:
//  ОписаниеИнсталляции - см. УстановитьПоставляемуюОбработкуВОбластьДанных.ОписаниеИнсталляции
//  БыстрыйДоступ       - см. УстановитьПоставляемуюОбработкуВОбластьДанных.БыстрыйДоступ
//  Задания             - см. УстановитьПоставляемуюОбработкуВОбластьДанных.Задания
//  Разделы             - см. УстановитьПоставляемуюОбработкуВОбластьДанных.Разделы
//  СправочникиИДокументы         - см. УстановитьПоставляемуюОбработкуВОбластьДанных.СправочникиИДокументы
//  ВариантыДополнительногоОтчета - см. УстановитьПоставляемуюОбработкуВОбластьДанных.ВариантыДополнительногоОтчета
//  Ответственный       - см. УстановитьПоставляемуюОбработкуВОбластьДанных.Ответственный
// 
Процедура УстановитьПоставляемуюОбработкуПриПолучении(Знач ОписаниеИнсталляции, Знач БыстрыйДоступ, Знач Задания, Знач Разделы, 
	Знач СправочникиИДокументы, Знач НастройкиРасположенияКоманд, Знач ВариантыДополнительногоОтчета, Знач Ответственный) Экспорт
	
	Попытка
		УстановитьПоставляемуюОбработкуВОбластьДанных(ОписаниеИнсталляции, БыстрыйДоступ, 
			Задания, Разделы, СправочникиИДокументы, НастройкиРасположенияКоманд, ВариантыДополнительногоОтчета, Ответственный);
	Исключение
		
		ТекстИсключения = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ПоставляемаяОбработка = Справочники.ПоставляемыеДополнительныеОтчетыИОбработки.ПолучитьСсылку(ОписаниеИнсталляции.Идентификатор);
		ОбработатьОшибкуУстановкиДополнительнойОбработкиВОбластьДанных(
			ПоставляемаяОбработка, ОписаниеИнсталляции.Инсталляция, ТекстИсключения);
			
	КонецПопытки;
	
КонецПроцедуры

// Выполняет установку поставляемой дополнительной обработки в текущую область данных.
//
// Параметры:
//  ОписаниеИнсталляции - Структура - сведения об установке поставляемой дополнительной обработки:
//    * Идентификатор - УникальныйИдентификатор - уникальный идентификатор ссылки
//                      элемента справочника ПоставляемыеДополнительныеОтчетыИОбработки.
//    * Представление - Строка - представление инсталляции поставляемой дополнительной
//      обработки (будет использоваться в качестве наименования элемента справочника
//      ДополнительныеОтчетыИОбработки).
//    * Инсталляция - УникальныйИдентификатор - уникальный идентификатор инсталляции
//      поставляемой дополнительной обработки (будет использоваться в качестве
//      уникального идентификатора ссылки справочника ДополнительныеОтчетыИОбработки).
//  БыстрыйДоступ - ТаблицаЗначений - настройки включения команд дополнительной
//     обработки в быстрый доступ пользователей приложения, колонки:
//    * ИдентификаторКоманды - Строка - идентификатор команды.
//    * Пользователь - СправочникСсылка.Пользователи - пользователь приложения.
//  Задания - ТаблицаЗначений - настройки выполнения команд дополнительной обработки
//      в качестве регламентных заданий, колонки:
//    * Идентификатор - Строка - идентификатор команды.
//    * РегламентноеЗаданиеРасписание - СписокЗначений:
//       ** Значение - РасписаниеРегламентногоЗадания - расписание.
//    * РегламентноеЗаданиеИспользование - Булево - признак включения выполнения команды
//          в качестве регламентного задания.
//  Разделы - ТаблицаЗначений - настройки включения команд для инсталляции поставляемой дополнительной обработки, колонки:
//    * Раздел - СправочникСсылка.ИдентификаторыОбъектовМетаданных
//  СправочникиИДокументы - ТаблицаЗначений:
//    * ОбъектНазначения - СправочникСсылка.ИдентификаторыОбъектовМетаданных
//  ВариантыДополнительногоОтчета - Массив - ключи вариантов отчетов дополнительного отчета.
//  Ответственный - СправочникСсылка.Пользователи
//
Процедура УстановитьПоставляемуюОбработкуВОбластьДанных(Знач ОписаниеИнсталляции, Знач БыстрыйДоступ, Знач Задания, Знач Разделы, 
	Знач СправочникиИДокументы, Знач НастройкиРасположенияКоманд, Знач ВариантыДополнительногоОтчета, Знач Ответственный) Экспорт
	
	Если Не ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
		Возврат;
	КонецЕсли;
	
	УстановитьПривилегированныйРежим(Истина);
	
	ЗаписьЖурналаРегистрации(
		НСтр("ru = 'Поставляемые дополнительные отчеты и обработки.Инициирована установка поставляемой обработки в область данных'",
		ОбщегоНазначения.КодОсновногоЯзыка()),
		УровеньЖурналаРегистрации.Информация,
		,
		Строка(ОписаниеИнсталляции.Идентификатор),
		Строка(ОписаниеИнсталляции.Инсталляция));
		
	НачатьТранзакцию();
	Попытка
		ПоставляемаяОбработка = Справочники.ПоставляемыеДополнительныеОтчетыИОбработки.ПолучитьСсылку(ОписаниеИнсталляции.Идентификатор);
		ПоставляемаяОбработкаСуществует = ОбщегоНазначения.СсылкаСуществует(ПоставляемаяОбработка);
		
		Блокировка = Новый БлокировкаДанных;
		Если ПоставляемаяОбработкаСуществует Тогда
			ИспользуемаяОбработкаСсылка = ИспользуемаяОбработка(ПоставляемаяОбработка, ОписаниеИнсталляции.Инсталляция);
			Если ЗначениеЗаполнено(ИспользуемаяОбработкаСсылка) Тогда
				ЭлементБлокировки = Блокировка.Добавить("Справочник.ДополнительныеОтчетыИОбработки");
				ЭлементБлокировки.УстановитьЗначение("Ссылка", ИспользуемаяОбработкаСсылка);
				ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.ИспользованиеПоставляемыхДополнительныхОтчетовИОбработокВОбластяхДанных");
				ЭлементБлокировки.УстановитьЗначение("ПоставляемаяОбработка", ПоставляемаяОбработка);
			КонецЕсли;
		КонецЕсли;
		ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.ОчередьИнсталляцииПоставляемыхДополнительныхОтчетовИОбработокВОбластиДанных");
		ЭлементБлокировки.УстановитьЗначение("ПоставляемаяОбработка", ПоставляемаяОбработка);
		Блокировка.Заблокировать();
			
		Набор = РегистрыСведений.ОчередьИнсталляцииПоставляемыхДополнительныхОтчетовИОбработокВОбластиДанных.СоздатьНаборЗаписей();
		Набор.Отбор.ПоставляемаяОбработка.Установить(ПоставляемаяОбработка);
		Набор.Записать();
		
		Если ПоставляемаяОбработкаСуществует Тогда
			АктуальныеКоманды = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ПоставляемаяОбработка, "Команды").Выгрузить();
			АктуальныеКоманды.Колонки.Добавить("РегламентноеЗаданиеРасписание", Новый ОписаниеТипов("СписокЗначений"));
			АктуальныеКоманды.Колонки.Добавить("РегламентноеЗаданиеИспользование", Новый ОписаниеТипов("Булево"));
			АктуальныеКоманды.Колонки.Добавить("РегламентноеЗаданиеGUID", Новый ОписаниеТипов("УникальныйИдентификатор"));
			
			Для Каждого АктуальнаяКоманда Из АктуальныеКоманды Цикл
				
				НастройкаЗадания = Задания.Найти(АктуальнаяКоманда.Идентификатор, "Идентификатор");
				Если НастройкаЗадания <> Неопределено Тогда
					ЗаполнитьЗначенияСвойств(АктуальнаяКоманда, НастройкаЗадания, "РегламентноеЗаданиеРасписание,РегламентноеЗаданиеИспользование");
				КонецЕсли;
				
			КонецЦикла;
			
			// Создается элемент справочника ДополнительныеОтчетыИОбработки, выступающий в роли используемой обработки.
			ИспользуемаяОбработкаСсылка = ИспользуемаяОбработка(ПоставляемаяОбработка, ОписаниеИнсталляции.Инсталляция);
			Если ЗначениеЗаполнено(ИспользуемаяОбработкаСсылка) Тогда
				ИспользуемаяОбработка = ИспользуемаяОбработкаСсылка.ПолучитьОбъект();
			Иначе
				ИспользуемаяОбработка = Справочники.ДополнительныеОтчетыИОбработки.СоздатьЭлемент();
			КонецЕсли;
			
			ЗаполнитьНастройкиИспользуемойОбработки(ИспользуемаяОбработка, ПоставляемаяОбработка);
			Если ЗначениеЗаполнено(Разделы) И Разделы.Количество() > 0 Тогда
				ИспользуемаяОбработка.Разделы.Загрузить(Разделы);
			КонецЕсли;
			
			Если ЗначениеЗаполнено(СправочникиИДокументы) И СправочникиИДокументы.Количество() > 0 Тогда
				ИспользуемаяОбработка.Назначение.Загрузить(СправочникиИДокументы);
				ИспользуемаяОбработка.ИспользоватьДляФормыСписка = НастройкиРасположенияКоманд.ИспользоватьДляФормыСписка;
				ИспользуемаяОбработка.ИспользоватьДляФормыОбъекта = НастройкиРасположенияКоманд.ИспользоватьДляФормыОбъекта;
			КонецЕсли;
			
			ИспользуемаяОбработка.Наименование = ОписаниеИнсталляции.Представление;
			ИспользуемаяОбработка.Ответственный = Ответственный;
			
			ИспользуемаяОбработка.ДополнительныеСвойства.Вставить("БыстрыйДоступ", БыстрыйДоступ);
			ИспользуемаяОбработка.ДополнительныеСвойства.Вставить("АктуальныеКоманды", АктуальныеКоманды);
			
			Если ИспользуемаяОбработка.ЭтоНовый() Тогда
				ИспользуемаяОбработка.УстановитьСсылкуНового(Справочники.ДополнительныеОтчетыИОбработки.ПолучитьСсылку(
					ОписаниеИнсталляции.Инсталляция));
			КонецЕсли;
			
			// Устанавливается связь между поставляемой и используемой обработкой
			НаборЗаписей = РегистрыСведений.ИспользованиеПоставляемыхДополнительныхОтчетовИОбработокВОбластяхДанных.СоздатьНаборЗаписей();
			НаборЗаписей.Отбор.ПоставляемаяОбработка.Установить(ПоставляемаяОбработка);
			Запись = НаборЗаписей.Добавить();
			Запись.ПоставляемаяОбработка = ПоставляемаяОбработка;
			Если ИспользуемаяОбработка.ЭтоНовый() Тогда
				Запись.ИспользуемаяОбработка = ИспользуемаяОбработка.ПолучитьСсылкуНового();
			Иначе
				Запись.ИспользуемаяОбработка = ИспользуемаяОбработка.Ссылка;
			КонецЕсли;
			НаборЗаписей.Записать();
			
			ИспользуемаяОбработка.Записать();
			
			// Размещение вариантов дополнительного отчета в разделах, которые выбрал пользователь
			// при установке (или разработчик при создании манифеста, если пользователь не изменял настройки по-умолчанию.
			Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ВариантыОтчетов") Тогда
				МодульВариантыОтчетов = ОбщегоНазначения.ОбщийМодуль("ВариантыОтчетов");
				Для Каждого ВариантДополнительногоОтчета Из ВариантыДополнительногоОтчета Цикл
					ВариантСсылка = МодульВариантыОтчетов.ВариантОтчета(ИспользуемаяОбработка.Ссылка, ВариантДополнительногоОтчета.Ключ);
					Если ВариантСсылка <> Неопределено Тогда
						Вариант = ВариантСсылка.ПолучитьОбъект();
						Вариант.Размещение.Очистить();
						Для Каждого ЭлементРазмещения Из ВариантДополнительногоОтчета.Размещение Цикл
							РазмещениеВарианта = Вариант.Размещение.Добавить();
							РазмещениеВарианта.Использование = Истина;
							РазмещениеВарианта.Подсистема = ЭлементРазмещения.Раздел;
							РазмещениеВарианта.Важный = ЭлементРазмещения.Важный;
							РазмещениеВарианта.СмТакже = ЭлементРазмещения.СмТакже;
						КонецЦикла;
						Вариант.Записать();
					КонецЕсли;
				КонецЦикла;
			КонецЕсли;
			
			МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");
			МодульСообщенияВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("СообщенияВМоделиСервиса");
			
			// Отправляется сообщение в МС об успешной установке обработки в области данных
			Сообщение = МодульСообщенияВМоделиСервиса.НовоеСообщение(
				СообщенияКонтрольДополнительныхОтчетовИОбработокИнтерфейс.СообщениеДополнительныйОтчетИлиОбработкаУстановлена());
			
			Сообщение.Body.Zone = МодульРаботаВМоделиСервиса.ЗначениеРазделителяСеанса();
			Сообщение.Body.Extension = ПоставляемаяОбработка.УникальныйИдентификатор();
			Сообщение.Body.Installation = ОписаниеИнсталляции.Инсталляция;
			
			МодульРаботаВМоделиСервисаБТСПовтИсп = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервисаБТСПовтИсп");
			МодульСообщенияВМоделиСервиса.ОтправитьСообщение(Сообщение,
				МодульРаботаВМоделиСервисаБТСПовтИсп.КонечнаяТочкаМенеджераСервиса(),  Истина);
			
			ЗаписьЖурналаРегистрации(НСтр("ru = 'Поставляемые дополнительные отчеты и обработки.Установка в область данных'",
				ОбщегоНазначения.КодОсновногоЯзыка()),
				УровеньЖурналаРегистрации.Информация,
				,
				ПоставляемаяОбработка,
				Строка(ОписаниеИнсталляции.Инсталляция));
				
		Иначе
			
			// Поставляемая обработка еще не синхронизировалась через поставляемые данные.
			// Она будет записана в очередь инсталляции и обработана после окончания синхронизации
			// поставляемых данных.
			
			Контекст = Новый Структура;
			Контекст.Вставить("БыстрыйДоступ", БыстрыйДоступ);
			Контекст.Вставить("Задания", Задания);
			Контекст.Вставить("Разделы", Разделы);
			Контекст.Вставить("СправочникиИДокументы", СправочникиИДокументы);
			Контекст.Вставить("НастройкиРасположенияКоманд", НастройкиРасположенияКоманд);
			Контекст.Вставить("ВариантыДополнительногоОтчета", ВариантыДополнительногоОтчета);
			Контекст.Вставить("Ответственный", Ответственный);
			Контекст.Вставить("Представление", ОписаниеИнсталляции.Представление);
			Контекст.Вставить("Инсталляция", ОписаниеИнсталляции.Инсталляция);
			
			Менеджер = РегистрыСведений.ОчередьИнсталляцииПоставляемыхДополнительныхОтчетовИОбработокВОбластиДанных.СоздатьМенеджерЗаписи();
			Менеджер.ПоставляемаяОбработка = ПоставляемаяОбработка;
			Менеджер.ПараметрыИнсталляции = Новый ХранилищеЗначения(Контекст);
			Менеджер.Записать();
			
			ЗаписьЖурналаРегистрации(НСтр("ru = 'Поставляемые дополнительные отчеты и обработки.Установка в область данных отложена'",
				ОбщегоНазначения.КодОсновногоЯзыка()),
				УровеньЖурналаРегистрации.Информация,
				,
				Строка(ОписаниеИнсталляции.Идентификатор),
				Строка(ОписаниеИнсталляции.Инсталляция));
			
		КонецЕсли;
		ЗафиксироватьТранзакцию();
		
	Исключение
		ОтменитьТранзакцию();
		ВызватьИсключение;
	КонецПопытки;
	
	МодульОбменСообщениями = ОбщегоНазначения.ОбщийМодуль("ОбменСообщениями");
	МодульОбменСообщениями.ДоставитьСообщения();

КонецПроцедуры

// АПК:134-вкл.

// Выполняет удаление поставляемой дополнительной обработки из текущей области данных.
//
// Параметры:
//  ПоставляемаяОбработка - СправочникСсылка.ПоставляемыеДополнительныеОтчетыИОбработки,
//  ИдентификаторИспользуемойОбработки - УникальныйИдентификатор - GUID существующего в области
//    данных элемента справочника ДополнительныеОтчетыИОбработки.
//
Процедура УдалитьПоставляемуюОбработкуИзОбластиДанных(Знач ПоставляемаяОбработка, Знач ИдентификаторИспользуемойОбработки) Экспорт
	
	Если Не ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
		Возврат;
	КонецЕсли;
	
	ТекстИсключения = "";
	УстановитьПривилегированныйРежим(Истина);
	НачатьТранзакцию();
	Попытка
		
		ИспользуемаяОбработка = Справочники.ДополнительныеОтчетыИОбработки.ПолучитьСсылку(
			ИдентификаторИспользуемойОбработки);
			
		Блокировка = Новый БлокировкаДанных;
		ЭлементБлокировки = Блокировка.Добавить("Справочник.ДополнительныеОтчетыИОбработки");
		ЭлементБлокировки.УстановитьЗначение("Ссылка", ИспользуемаяОбработка);
		ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.ИспользованиеПоставляемыхДополнительныхОтчетовИОбработокВОбластяхДанных");
		ЭлементБлокировки.УстановитьЗначение("ПоставляемаяОбработка", ПоставляемаяОбработка);
		Блокировка.Заблокировать();
		
		// Очистим связь между поставляемой и используемой обработкой
		НаборЗаписей = РегистрыСведений.ИспользованиеПоставляемыхДополнительныхОтчетовИОбработокВОбластяхДанных.СоздатьНаборЗаписей();
		НаборЗаписей.Отбор.ПоставляемаяОбработка.Установить(ПоставляемаяОбработка);
		
		// Удалим используемую обработку
		ОбъектОбработки = ИспользуемаяОбработка.ПолучитьОбъект();
		Если ОбъектОбработки <> Неопределено Тогда
			ОбъектОбработки.Удалить();
		КонецЕсли;
		
		НаборЗаписей.Записать();
		
		МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");
		МодульСообщенияВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("СообщенияВМоделиСервиса");
		
		// Отправим в МС сообщение об удалении обработки из области данных
		Сообщение = МодульСообщенияВМоделиСервиса.НовоеСообщение(
			СообщенияКонтрольДополнительныхОтчетовИОбработокИнтерфейс.СообщениеДополнительныйОтчетИлиОбработкаУдалена());
		
		Сообщение.Body.Zone = МодульРаботаВМоделиСервиса.ЗначениеРазделителяСеанса();
		Сообщение.Body.Extension = ПоставляемаяОбработка.УникальныйИдентификатор();
		Сообщение.Body.Installation = ИдентификаторИспользуемойОбработки;
		
		МодульРаботаВМоделиСервисаБТСПовтИсп = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервисаБТСПовтИсп");
		
		МодульСообщенияВМоделиСервиса.ОтправитьСообщение(
			Сообщение,
			МодульРаботаВМоделиСервисаБТСПовтИсп.КонечнаяТочкаМенеджераСервиса());
		
		ЗаписьЖурналаРегистрации(НСтр("ru = 'Поставляемые дополнительные отчеты и обработки.Удаление из области данных'",
			ОбщегоНазначения.КодОсновногоЯзыка()),
			УровеньЖурналаРегистрации.Информация,
			,
			ПоставляемаяОбработка,
			Строка(ИдентификаторИспользуемойОбработки));
		
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ТекстИсключения = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
	КонецПопытки;
			
	Если Не ПустаяСтрока(ТекстИсключения) Тогда
		
		ЗаписьЖурналаРегистрации(НСтр("ru = 'Поставляемые дополнительные отчеты и обработки.Ошибка удаления из область данных'",
			ОбщегоНазначения.КодОсновногоЯзыка()),
			УровеньЖурналаРегистрации.Ошибка,
			,
			ПоставляемаяОбработка,
			Строка(ИдентификаторИспользуемойОбработки) + Символы.ПС + Символы.ВК + ТекстИсключения);
			
		МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");
		МодульСообщенияВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("СообщенияВМоделиСервиса");
		МодульРаботаВМоделиСервисаБТСПовтИсп = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервисаБТСПовтИсп");
		
		// Отправляется сообщение в МС об ошибке установки обработки в области данных
		Сообщение = МодульСообщенияВМоделиСервиса.НовоеСообщение(
			СообщенияКонтрольДополнительныхОтчетовИОбработокИнтерфейс.СообщениеОшибкаУдаленияДополнительногоОтчетаИлиОбработки());
		
		Сообщение.Body.Zone = МодульРаботаВМоделиСервиса.ЗначениеРазделителяСеанса();
		Сообщение.Body.Extension = ПоставляемаяОбработка.УникальныйИдентификатор();
		Сообщение.Body.Installation = ИдентификаторИспользуемойОбработки;
		Сообщение.Body.ErrorDescription = ТекстИсключения;
		
		МодульСообщенияВМоделиСервиса.ОтправитьСообщение(Сообщение, МодульРаботаВМоделиСервисаБТСПовтИсп.КонечнаяТочкаМенеджераСервиса());
	КонецЕсли;	
	
КонецПроцедуры

// Выполняет удаление поставляемой дополнительной обработки из всех областей данных
//  текущей информационной базы.
//
// Параметры:
//  ПоставляемаяОбработка - СправочникСсылка.ПоставляемыеДополнительныеОтчетыИОбработки.
//
Процедура ОтозватьПоставляемуюДополнительнуюОбработку(Знач ПоставляемаяОбработка) Экспорт
	
	Если Не ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.ОчередьЗаданий") Тогда
		Возврат;
	КонецЕсли;
	
	НачатьТранзакцию();
	Попытка
		Блокировка = Новый БлокировкаДанных;
		ЭлементБлокировки = Блокировка.Добавить("Справочник.ПоставляемыеДополнительныеОтчетыИОбработки");
		ЭлементБлокировки.УстановитьЗначение("Ссылка", ПоставляемаяОбработка);
		Блокировка.Заблокировать();
		
		Инсталляции = ПереченьИнсталляций(ПоставляемаяОбработка);
		Для Каждого Инсталляция Из Инсталляции Цикл
			
			ПараметрыМетода = Новый Массив;
			ПараметрыМетода.Добавить(ПоставляемаяОбработка);
			ПараметрыМетода.Добавить(Инсталляция.ИспользуемаяОбработка.УникальныйИдентификатор());
			
			ПараметрыЗадания = Новый Структура;
			ПараметрыЗадания.Вставить("ИмяМетода"    , "ДополнительныеОтчетыИОбработкиВМоделиСервиса.УдалитьПоставляемуюОбработкуИзОбластиДанных");
			ПараметрыЗадания.Вставить("Параметры"    , ПараметрыМетода);
			ПараметрыЗадания.Вставить("КоличествоПовторовПриАварийномЗавершении", 3);
			ПараметрыЗадания.Вставить("ОбластьДанных", Инсталляция.ОбластьДанных);
			
			МодульОчередьЗаданий = ОбщегоНазначения.ОбщийМодуль("ОчередьЗаданий");
			МодульОчередьЗаданий.ДобавитьЗадание(ПараметрыЗадания);
			
		КонецЦикла;
		
		ОбъектОбработки = ПоставляемаяОбработка.ПолучитьОбъект();
		ОбъектОбработки.ОбменДанными.Загрузка = Истина;
		ОбъектОбработки.Удалить();
		
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ВызватьИсключение;
	КонецПопытки;
	
КонецПроцедуры

// Выполняет обработку ошибки при установки дополнительной обработки в область данных.
//
// Параметры:
//  ПоставляемаяОбработка - СправочникСсылка.ПоставляемыеДополнительныеОтчетыИОбработки,
//  ИдентификаторИнсталляции - УникальныйИдентификатор,
//  ТекстИсключения - Строка - текст исключения.
//
Процедура ОбработатьОшибкуУстановкиДополнительнойОбработкиВОбластьДанных(Знач ПоставляемаяОбработка, Знач ИдентификаторИнсталляции, Знач ТекстИсключения) Экспорт
	
	Если Не ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
		Возврат;
	КонецЕсли;
	
	ЗаписьЖурналаРегистрации(НСтр("ru = 'Поставляемые дополнительные отчеты и обработки.Ошибка установки в область данных'",
		ОбщегоНазначения.КодОсновногоЯзыка()),
		УровеньЖурналаРегистрации.Ошибка,
		,
		ПоставляемаяОбработка,
		Строка(ИдентификаторИнсталляции) + Символы.ПС + Символы.ВК + ТекстИсключения);
	
	НачатьТранзакцию();		
	Попытка
		
		МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");
		МодульСообщенияВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("СообщенияВМоделиСервиса");
		
		// Отправляется сообщение в МС об ошибке установки обработки в области данных
		Сообщение = МодульСообщенияВМоделиСервиса.НовоеСообщение(
			СообщенияКонтрольДополнительныхОтчетовИОбработокИнтерфейс.СообщениеОшибкаУстановкиДополнительногоОтчетаИлиОбработки());
			
		Сообщение.Body.Zone = МодульРаботаВМоделиСервиса.ЗначениеРазделителяСеанса();
		Сообщение.Body.Extension = ПоставляемаяОбработка.УникальныйИдентификатор();
		Сообщение.Body.Installation = ИдентификаторИнсталляции;
		Сообщение.Body.ErrorDescription = ТекстИсключения;
		
		МодульРаботаВМоделиСервисаБТСПовтИсп = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервисаБТСПовтИсп");
		МодульСообщенияВМоделиСервиса.ОтправитьСообщение(
			Сообщение,
			МодульРаботаВМоделиСервисаБТСПовтИсп.КонечнаяТочкаМенеджераСервиса(),
			Истина);
	
		ЗафиксироватьТранзакцию();

	Исключение
		ОтменитьТранзакцию();
		ВызватьИсключение;
	КонецПопытки;
	
	МодульОбменСообщениями = ОбщегоНазначения.ОбщийМодуль("ОбменСообщениями");
	МодульОбменСообщениями.ДоставитьСообщения();
	
КонецПроцедуры

// Возвращает параметры подключения поставляемой дополнительной обработки.
//
// Параметры:
//  ИспользуемаяОбработка - СправочникСсылка.ДополнительныеОтчетыИОбработки.
//
// Возвращаемое значение:
//   Структура:
//   * ХранилищеОбработки - ХранилищеЗначения - содержит ДвоичныеДанные дополнительного отчета
//                                              или обработки,
//   * БезопасныйРежим - Булево - флаг подключения обработки в безопасном режиме.
//
Функция ПараметрыПодключенияИспользуемойОбработки(Знач ИспользуемаяОбработка) Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	
	ПоставляемаяОбработка = ПоставляемаяОбработка(ИспользуемаяОбработка);
	Если ЗначениеЗаполнено(ПоставляемаяОбработка) Тогда
		
		Свойства = "ИмяОбъекта, БезопасныйРежим, ХранилищеОбработки, ВерсияGUID";
		Результат = Новый Структура(Свойства);
		ЗаполнитьЗначенияСвойств(Результат, ОбщегоНазначения.ЗначенияРеквизитовОбъекта(ПоставляемаяОбработка, Свойства));
		Возврат Результат;
		
	КонецЕсли;
	
КонецФункции

// Формирует список параметров ИБ.
//
// Параметры:
//   ТаблицаПараметров - ТаблицаЗначений - таблица описания параметров.
//
Процедура ПриЗаполненииТаблицыПараметровИБ(Знач ТаблицаПараметров) Экспорт
	
	Если ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
		
		МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");
		МодульРаботаВМоделиСервиса.ДобавитьКонстантуВТаблицуПараметровИБ(ТаблицаПараметров, "ИспользованиеКаталогаДополнительныхОтчетовИОбработокВМоделиСервиса");
		МодульРаботаВМоделиСервиса.ДобавитьКонстантуВТаблицуПараметровИБ(ТаблицаПараметров, "ИспользоватьПрофилиБезопасностиДляДОО");
		МодульРаботаВМоделиСервиса.ДобавитьКонстантуВТаблицуПараметровИБ(ТаблицаПараметров, "МинимальныйИнтервалРегламентныхЗаданийДОИОВМоделиСервиса");
		МодульРаботаВМоделиСервиса.ДобавитьКонстантуВТаблицуПараметровИБ(ТаблицаПараметров, "НезависимоеИспользованиеДополнительныхОтчетовИОбработокВМоделиСервиса");
		МодульРаботаВМоделиСервиса.ДобавитьКонстантуВТаблицуПараметровИБ(ТаблицаПараметров, "РазрешитьВыполнениеДООРегламентнымиЗаданиямиВМоделиСервиса");
		
		// Константы были переименованы. Менеджер сервиса отправляет параметры со старыми именами констант.
		// Для поддержки совместимости добавляются параметры со старыми именами констант.
		СтрокаПараметра = МодульРаботаВМоделиСервиса.ДобавитьКонстантуВТаблицуПараметровИБ(ТаблицаПараметров, "РазрешитьВыполнениеДООРегламентнымиЗаданиямиВМоделиСервиса");
		СтрокаПараметра.Имя = "РазрешитьВыполнениеДополнительныхОтчетовИОбработокРегламентнымиЗаданиямиВМоделиСервиса";
		СтрокаПараметра = МодульРаботаВМоделиСервиса.ДобавитьКонстантуВТаблицуПараметровИБ(ТаблицаПараметров, "МинимальныйИнтервалРегламентныхЗаданийДОИОВМоделиСервиса");
		СтрокаПараметра.Имя = "МинимальныйИнтервалРегламентныхЗаданийДополнительныхОтчетовИОбработокВМоделиСервиса";
		СтрокаПараметра = МодульРаботаВМоделиСервиса.ДобавитьКонстантуВТаблицуПараметровИБ(ТаблицаПараметров, "ИспользоватьПрофилиБезопасностиДляДОО");
		СтрокаПараметра.Имя = "ИспользоватьПрофилиБезопасностиДляДОиО";
		
	КонецЕсли;
	
КонецПроцедуры

// Вызывается перед попыткой записи значений параметров ИБ в одноименные
// константы.
//
// Параметры:
//   ЗначенияПараметров - Структура - значения параметров которые требуется установить.
//   В случае если значение параметра устанавливается в данной процедуре из структуры
//   необходимо удалить соответствующую пару КлючИЗначение.
//
Процедура ПриУстановкеЗначенийПараметровИБ(Знач ЗначенияПараметров) Экспорт
	
	// Константы были переименованы. Менеджер сервиса отправляет параметры со старыми именами констант.
	// Для поддержки совместимости удаляются параметры со старыми именами констант и добавляются с новыми.
	РазрешитьВыполнениеДООРегламентнымиЗаданиямиВМоделиСервиса = Неопределено;
	МинимальныйИнтервалРегламентныхЗаданийДОИОВМоделиСервиса = Неопределено;
	ИспользоватьПрофилиБезопасностиДляДОО = Неопределено;
	
	Если ЗначенияПараметров.Свойство("РазрешитьВыполнениеДополнительныхОтчетовИОбработокРегламентнымиЗаданиямиВМоделиСервиса",
		РазрешитьВыполнениеДООРегламентнымиЗаданиямиВМоделиСервиса) Тогда
		
		ЗначенияПараметров.Вставить("РазрешитьВыполнениеДООРегламентнымиЗаданиямиВМоделиСервиса", РазрешитьВыполнениеДООРегламентнымиЗаданиямиВМоделиСервиса);
		ЗначенияПараметров.Удалить("РазрешитьВыполнениеДополнительныхОтчетовИОбработокРегламентнымиЗаданиямиВМоделиСервиса");
		
	КонецЕсли;
	
	Если ЗначенияПараметров.Свойство("РазрешитьВыполнениеДОИОРегламентнымиЗаданиямиВМоделиСервиса",
		РазрешитьВыполнениеДООРегламентнымиЗаданиямиВМоделиСервиса) Тогда
		
		ЗначенияПараметров.Вставить("РазрешитьВыполнениеДООРегламентнымиЗаданиямиВМоделиСервиса", РазрешитьВыполнениеДООРегламентнымиЗаданиямиВМоделиСервиса);
		ЗначенияПараметров.Удалить("РазрешитьВыполнениеДОИОРегламентнымиЗаданиямиВМоделиСервиса");
		
	КонецЕсли;
	
	Если ЗначенияПараметров.Свойство("МинимальныйИнтервалРегламентныхЗаданийДополнительныхОтчетовИОбработокВМоделиСервиса",
		МинимальныйИнтервалРегламентныхЗаданийДОИОВМоделиСервиса) Тогда
		
		ЗначенияПараметров.Вставить("МинимальныйИнтервалРегламентныхЗаданийДОИОВМоделиСервиса", МинимальныйИнтервалРегламентныхЗаданийДОИОВМоделиСервиса);
		ЗначенияПараметров.Удалить("МинимальныйИнтервалРегламентныхЗаданийДополнительныхОтчетовИОбработокВМоделиСервиса");
		
	КонецЕсли;
	
	Если ЗначенияПараметров.Свойство("ИспользоватьПрофилиБезопасностиДляДОиО",
		ИспользоватьПрофилиБезопасностиДляДОО) Тогда
		
		ЗначенияПараметров.Вставить("ИспользоватьПрофилиБезопасностиДляДОО", ИспользоватьПрофилиБезопасностиДляДОО);
		ЗначенияПараметров.Удалить("ИспользоватьПрофилиБезопасностиДляДОиО");
		
	КонецЕсли;
	
КонецПроцедуры

// Обработчик события ПриОпределенииПсевдонимовОбработчиков.
//
// Заполняет соответствие имен методов их псевдонимам для вызова из очереди заданий
//
// Параметры:
//  СоответствиеИменПсевдонимам - Соответствие из КлючИЗначение:
//   Ключ - псевдоним метода, например ОчиститьОбластьДанных
//   Значение - имя метода для вызова, например РаботаВМоделиСервиса.ОчиститьОбластьДанных
//    В качестве значения можно указать Неопределено, в этом случае считается что имя 
//    совпадает с псевдонимом.
//
Процедура ПриОпределенииПсевдонимовОбработчиков(СоответствиеИменПсевдонимам) Экспорт
	
	СоответствиеИменПсевдонимам.Вставить("ДополнительныеОтчетыИОбработкиВМоделиСервиса.АктуализацияНастроекИспользуемойОбработки");
	// Совместимость с версиями БСП 2.2.1.25 и ниже
	СоответствиеИменПсевдонимам.Вставить("ДополнительныеОтчетыИОбработкиВМоделиСервиса.УстановитьПоставляемуюОбработкуВОбластьДанных", 
		"ДополнительныеОтчетыИОбработкиВМоделиСервиса.УстановитьПоставляемуюОбработкуПриПолучении");
	СоответствиеИменПсевдонимам.Вставить("ДополнительныеОтчетыИОбработкиВМоделиСервиса.УстановитьПоставляемуюОбработкуПриПолучении");
	СоответствиеИменПсевдонимам.Вставить("ДополнительныеОтчетыИОбработкиВМоделиСервиса.УдалитьПоставляемуюОбработкуИзОбластиДанных");
	СоответствиеИменПсевдонимам.Вставить(Метаданные.РегламентныеЗадания.ЗапускДополнительныхОбработок.ИмяМетода);
	
КонецПроцедуры

// Зарегистрировать обработчики поставляемых данных
//
// При получении уведомления о доступности новых общих данных, вызывается процедуры
// ДоступныНовыеДанные модулей, зарегистрированных через ПолучитьОбработчикиПоставляемыхДанных.
// В процедуру передается Дескриптор - ОбъектXDTO Descriptor.
// 
// В случае, если ДоступныНовыеДанные устанавливает аргумент Загружать в значение Истина, 
// данные загружаются, дескриптор и путь к файлу с данными передаются в процедуру 
// ОбработатьНовыеДанные. Файл будет автоматически удален после завершения процедуры.
// Если в менеджере сервиса не был указан файл - значение аргумента равно Неопределено.
//
// Параметры: 
//   Обработчики - см. ПоставляемыеДанныеПереопределяемый.ПолучитьОбработчикиПоставляемыхДанных.Обработчики
//
Процедура ПриОпределенииОбработчиковПоставляемыхДанных(Обработчики) Экспорт
	
	Обработчик = Обработчики.Добавить();
	Обработчик.ВидДанных = ИдентификаторВидаПоставляемыхДанных();
	Обработчик.КодОбработчика = ИдентификаторВидаПоставляемыхДанных();
	Обработчик.Обработчик = ДополнительныеОтчетыИОбработкиВМоделиСервиса;
	
КонецПроцедуры

// Заполняет переданный массив общими модулями, которые являются обработчиками интерфейсов
//  принимаемых сообщений.
//
// Параметры:
//  МассивОбработчиков - Массив
//
Процедура РегистрацияИнтерфейсовПринимаемыхСообщений(МассивОбработчиков) Экспорт
	
	МассивОбработчиков.Добавить(СообщенияУправленияДополнительнымиОтчетамиИОбработкамиИнтерфейс);
	
КонецПроцедуры

// Заполняет переданный массив общими модулями, которые являются обработчиками интерфейсов
//  отправляемых сообщений.
//
// Параметры:
//  МассивОбработчиков - Массив
//
Процедура РегистрацияИнтерфейсовОтправляемыхСообщений(МассивОбработчиков) Экспорт
	
	МассивОбработчиков.Добавить(СообщенияКонтрольДополнительныхОтчетовИОбработокИнтерфейс);
	
КонецПроцедуры

// Вызывается при определении версии интерфейса сообщений, поддерживаемой как ИБ-корреспондентом,
//  так и текущей ИБ. В данной процедуре предполагается реализовывать механизмы поддержки обратной совместимости
//  со старыми версиями ИБ-корреспондентов.
//
// Параметры:
//  ИнтерфейсСообщения - Строка - название программного интерфейса сообщения, для которого определяется версия
//  ПараметрыПодключения - Структура - параметры подключения к ИБ-корреспонденту
//  ПредставлениеПолучателя - Строка - представление ИБ-корреспондента
//  Результат - Строка - определяемая версия. Значение данного параметра может быть изменено в данной процедуре.
//
Процедура ПриОпределенииВерсииИнтерфейсаКорреспондента(Знач ИнтерфейсСообщения, Знач ПараметрыПодключения, Знач ПредставлениеПолучателя, Результат) Экспорт
	
	// Совместимость с версиями МС, в которых интерфейс ApplicationExtensionsControl являлся
	// составной частью интерфейса RemoteAdministrationControl.
	
	Если ОбщегоНазначения.РазделениеВключено()
		И Результат = Неопределено
		И ИнтерфейсСообщения = "ApplicationExtensionsControl" Тогда
		
		ПроверяемыйИнтерфейс = "RemoteAdministrationControl";
		МодульИнтерфейсыСообщенийВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("ИнтерфейсыСообщенийВМоделиСервиса");
		ВерсияИнтерфейсаКонтроляУдаленногоАдминистрирования = МодульИнтерфейсыСообщенийВМоделиСервиса.ВерсияИнтерфейсаКорреспондента(
			ПроверяемыйИнтерфейс, ПараметрыПодключения, ПредставлениеПолучателя);
		
		Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ВерсияИнтерфейсаКонтроляУдаленногоАдминистрирования, "1.0.2.4") >= 0 Тогда
			Результат = "1.0.0.1";
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#КонецОбласти

#Область ТехнологияСервиса

#Область ВыгрузкаЗагрузкаОбластейДанных

// См. ВыгрузкаЗагрузкаДанныхПереопределяемый.ПриЗаполненииТиповИсключаемыхИзВыгрузкиЗагрузки.
Процедура ПриЗаполненииТиповИсключаемыхИзВыгрузкиЗагрузки(Типы) Экспорт
	
	Типы.Добавить(Метаданные.РегистрыСведений.ИспользованиеПоставляемыхДополнительныхОтчетовИОбработокВОбластяхДанных);
	Типы.Добавить(Метаданные.РегистрыСведений.ОчередьИнсталляцииПоставляемыхДополнительныхОтчетовИОбработокВОбластиДанных);
	
КонецПроцедуры

#КонецОбласти

#КонецОбласти

#КонецОбласти

#Область ОбработчикиРегламентныхЗаданий

// Процедура вызывается в качестве регламентного задания после получения новой версии дополнительной
//  обработки из каталога дополнительных отчетов и обработок менеджера сервиса.
//
// Параметры:
//  Ссылка - СправочникСсылка.ДополнительныеОтчетыИОбработки
//
Процедура АктуализацияНастроекИспользуемойОбработки(Знач Ссылка) Экспорт
	
	НачатьТранзакцию();
	Попытка
		ПоставляемаяОбработка = ПоставляемаяОбработка(Ссылка);
		Если Не ЗначениеЗаполнено(ПоставляемаяОбработка) Тогда
			ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Дополнительная обработка с идентификатором %1 не является поставляемой.'"),
				Строка(Ссылка.УникальныйИдентификатор()));
		КонецЕсли;
			
		Блокировка = Новый БлокировкаДанных;
		ЭлементБлокировки = Блокировка.Добавить("Справочник.ПоставляемыеДополнительныеОтчетыИОбработки");
		ЭлементБлокировки.УстановитьЗначение("Ссылка", ПоставляемаяОбработка);
		ЭлементБлокировки.Режим = РежимБлокировкиДанных.Разделяемый;
		ЭлементБлокировки = Блокировка.Добавить("Справочник.ДополнительныеОтчетыИОбработки");
		ЭлементБлокировки.УстановитьЗначение("Ссылка", Ссылка);
		Блокировка.Заблокировать();
		
		ИспользуемаяОбработка = Ссылка.ПолучитьОбъект();
		УстановитьПривилегированныйРежим(Истина);
		ЗаполнитьНастройкиИспользуемойОбработки(ИспользуемаяОбработка, ПоставляемаяОбработка.ПолучитьОбъект());
		УстановитьПривилегированныйРежим(Ложь);
		ИспользуемаяОбработка.Записать();
		
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ВызватьИсключение;
	КонецПопытки;
КонецПроцедуры

#КонецОбласти

#Область ПоставляемыеДанные

// АПК:299-выкл Обработчики поставляемых данных

// Вызывается при получении уведомления о новых данных.
// В теле следует проверить, необходимы ли эти данные приложению, 
// и если да - установить флажок Загружать.
// 
// Параметры:
//   Дескриптор   - ОбъектXDTO - Descriptor.
//   Загружать    - Булево - возвращаемое.
//
Процедура ДоступныНовыеДанные(Знач Дескриптор, Загружать) Экспорт
	
	Если Дескриптор.DataType = ИдентификаторВидаПоставляемыхДанных() Тогда
		
		ОписаниеПоставляемойОбработки = РазобратьДескрипторПоставляемыхДанных(Дескриптор);
		
		Чтение = Новый ЧтениеXML();
		Чтение.УстановитьСтроку(ОписаниеПоставляемойОбработки.Совместимость);
		Чтение.ПерейтиКСодержимому();
		ТаблицаСовместимостиXDTO = ФабрикаXDTO.ПрочитатьXML(Чтение, ФабрикаXDTO.Тип(Чтение.URIПространстваИмен, Чтение.Имя));
		ТаблицаСовместимости = ПрочитатьТаблицуСовместимости(ТаблицаСовместимостиXDTO);
		
		Если ПроверитьСовместимостьПоставляемойОбработки(ТаблицаСовместимости) Тогда // Если обработка совместима с ИБ
			
			Загружать = Истина;
			
		Иначе
			
			Загружать = Ложь;
			
			ЗаписьЖурналаРегистрации(
				НСтр("ru = 'Поставляемые дополнительные отчеты и обработки.Загрузка поставляемой обработки отменена'", 
				ОбщегоНазначения.КодОсновногоЯзыка()),
				УровеньЖурналаРегистрации.Информация,
				,
				,
				НСтр("ru = 'Поставляемая обработка несовместима с данной конфигурацией'") + Символы.ПС + Символы.ВК + ОписаниеПоставляемойОбработки.Совместимость);
			
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

// Вызывается после вызова ДоступныНовыеДанные, позволяет разобрать данные.
//
// Параметры:
//   Дескриптор   - ОбъектXDTO - дескриптор.
//   ПутьКФайлу   - Строка, Неопределено - полное имя извлеченного файла. Файл будет автоматически удален 
//                  после завершения процедуры. Если в менеджере сервиса не был
//                  указан файл - значение аргумента равно Неопределено.
//
Процедура ОбработатьНовыеДанные(Знач Дескриптор, Знач ПутьКФайлу) Экспорт
	
	Если Дескриптор.DataType = ИдентификаторВидаПоставляемыхДанных() Тогда
		ОбработатьПоставляемыеДополнительныеОтчетыИОбработки(Дескриптор, ПутьКФайлу);
	КонецЕсли;
	
КонецПроцедуры

// Вызывается при отмене обработки данных в случае сбоя
//
Процедура ОбработкаДанныхОтменена(Знач Дескриптор) Экспорт 
	
КонецПроцедуры

// АПК:299-вкл

#КонецОбласти

#Область ОбработчикиОбновления

// Блокирует дополнительные отчеты и обработки в областях данных для
// получения новых версий из менеджера сервиса.
//
Процедура ЗаблокироватьДополнительныеОтчетыИОбработкиДляОбновления() Экспорт
	
	Если Не ОбщегоНазначения.РазделениеВключено() Тогда
		Возврат;
	КонецЕсли;
		
	УстановитьПривилегированныйРежим(Истина);
	
	ТекстЗапроса =
	"ВЫБРАТЬ
	|	ПоставляемыеДополнительныеОтчетыИОбработки.Ссылка КАК Ссылка
	|ИЗ
	|	Справочник.ПоставляемыеДополнительныеОтчетыИОбработки КАК ПоставляемыеДополнительныеОтчетыИОбработки
	|ГДЕ
	|	НЕ ПоставляемыеДополнительныеОтчетыИОбработки.Ссылка В
	|				(ВЫБРАТЬ РАЗЛИЧНЫЕ
	|					ПоставляемыеДополнительныеОтчетыИОбработкиСовместимость.Ссылка
	|				ИЗ
	|					Справочник.ПоставляемыеДополнительныеОтчетыИОбработки.Совместимость КАК ПоставляемыеДополнительныеОтчетыИОбработкиСовместимость
	|				ГДЕ
	|					ПоставляемыеДополнительныеОтчетыИОбработкиСовместимость.Версия = &Версия)
	|	И ПоставляемыеДополнительныеОтчетыИОбработки.КонтролироватьСовместимостьСВерсиямиКонфигурации = ИСТИНА";
	Запрос = Новый Запрос(ТекстЗапроса);
	Запрос.УстановитьПараметр("Версия", Метаданные.Версия);
	
	НачатьТранзакцию();
	Попытка
		Блокировка = Новый БлокировкаДанных;
		Блокировка.Добавить("Справочник.ПоставляемыеДополнительныеОтчетыИОбработки");
		Блокировка.Заблокировать();
		
		БлокируемыеОбработки = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");
		Для Каждого БлокируемаяОбработка Из БлокируемыеОбработки Цикл
			
			ПоставляемаяОбработка = БлокируемаяОбработка.ПолучитьОбъект(); // СправочникОбъект.ПоставляемыеДополнительныеОтчетыИОбработки -
			ПоставляемаяОбработка.Публикация = Перечисления.ВариантыПубликацииДополнительныхОтчетовИОбработок.Отключена;
			ПоставляемаяОбработка.ПричинаОтключения = Перечисления.ПричиныОтключенияДополнительныхОтчетовИОбработокВМоделиСервиса.ОбновлениеВерсииКонфигурации;
			ПоставляемаяОбработка.Записать();
			
		КонецЦикла;
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ВызватьИсключение;
	КонецПопытки;
	
КонецПроцедуры

#КонецОбласти

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

// Возвращает поставляемую обработку, соответствующую используемой обработке.
//
// Параметры:
//   ИспользуемаяОбработка - СправочникСсылка.ДополнительныеОтчетыИОбработки - дополнительная обработка.
//
// Возвращаемое значение:
//  СправочникСсылка.ПоставляемыеДополнительныеОтчетыИОбработки
//
Функция ПоставляемаяОбработка(ИспользуемаяОбработка)
	
	Если Не ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
		ТекстСообщения = НСтр("ru = 'Использование функции %1 доступно только сеансов с установленным разделением данных.'");
		ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстСообщения,
			"ДополнительныеОтчетыИОбработкиВМоделиСервиса.ПоставляемаяОбработка");
		ВызватьИсключение ТекстСообщения;
	КонецЕсли;
	
	ТекстЗапроса = "ВЫБРАТЬ ПЕРВЫЕ 1
	               |	Инсталляции.ПоставляемаяОбработка КАК ПоставляемаяОбработка
	               |ИЗ
	               |	РегистрСведений.ИспользованиеПоставляемыхДополнительныхОтчетовИОбработокВОбластяхДанных КАК Инсталляции
	               |ГДЕ
	               |	Инсталляции.ИспользуемаяОбработка = &ИспользуемаяОбработка";
	Запрос = Новый Запрос(ТекстЗапроса);
	Запрос.УстановитьПараметр("ИспользуемаяОбработка", ИспользуемаяОбработка);
	УстановитьПривилегированныйРежим(Истина);
	Результат = Запрос.Выполнить();
	Если Результат.Пустой() Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	Выборка = Результат.Выбрать();
	Выборка.Следующий();
	Возврат Выборка.ПоставляемаяОбработка;
	
КонецФункции

// Возвращает используемую обработку, соответствующую поставляемой обработке для текущего значения разделителя ОбластьДанных.
//
// Параметры:
//  ПоставляемаяОбработка - СправочникСсылка.ПоставляемыеДополнительныеОтчетыИОбработки - поставляемая обработка.
//
// Возвращаемое значение:
//  СправочникСсылка.ДополнительныеОтчетыИОбработки
//
Функция ИспользуемаяОбработка(ПоставляемаяОбработка, ИдентификаторИнсталляции = Неопределено)
	
	Если Не ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
		ТекстСообщения = НСтр("ru = 'Использование функции %1 доступно только сеансов с установленным разделением данных.'");
		ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстСообщения,
			"ДополнительныеОтчетыИОбработкиВМоделиСервиса.ИспользуемаяОбработка");
		ВызватьИсключение ТекстСообщения;
	КонецЕсли;
	
	ТекстЗапроса = "ВЫБРАТЬ
	               |	Инсталляции.ИспользуемаяОбработка КАК ИспользуемаяОбработка
	               |ИЗ
	               |	РегистрСведений.ИспользованиеПоставляемыхДополнительныхОтчетовИОбработокВОбластяхДанных КАК Инсталляции
	               |ГДЕ
	               |	Инсталляции.ПоставляемаяОбработка = &ПоставляемаяОбработка";
	Запрос = Новый Запрос(ТекстЗапроса);
	Запрос.УстановитьПараметр("ПоставляемаяОбработка", ПоставляемаяОбработка);
	УстановитьПривилегированныйРежим(Истина);
	
	Результат = Запрос.Выполнить();
	Если Не Результат.Пустой() Тогда
		Выборка = Результат.Выбрать();
		Выборка.Следующий();
		Возврат Выборка.ИспользуемаяОбработка;
	КонецЕсли;
	
	Если ИдентификаторИнсталляции = Неопределено Тогда
		Возврат Неопределено;	
	КонецЕсли;
	
	ИспользуемаяОбработка = Справочники.ДополнительныеОтчетыИОбработки.ПолучитьСсылку(
		Новый УникальныйИдентификатор(ИдентификаторИнсталляции));
			
	Если ОбщегоНазначения.СсылкаСуществует(ИспользуемаяОбработка) Тогда
		Возврат ИспользуемаяОбработка;
	Иначе
		Возврат Неопределено;	
	КонецЕсли;
	
КонецФункции

// Возвращает перечень инсталляций поставляемой дополнительной обработки в области данных.
//
// Параметры:
//  ПоставляемаяОбработка - СправочникСсылка.ПоставляемыеДополнительныеОтчетыИОбработки - поставляемая обработка.
//
// Возвращаемое значение:
//  ТаблицаЗначений:
//    * ОбластьДанных - Число - число длиной 7 символов, номер области данных.
//    * ИспользуемаяОбработка - СправочникСсылка.ДополнительныеОтчетыИОбработки - дополнительная обработка.
//
Функция ПереченьИнсталляций(Знач ПоставляемаяОбработка)
	
	ТекстЗапроса =
		"ВЫБРАТЬ
		|	Инсталляции.ОбластьДанныхВспомогательныеДанные КАК ОбластьДанных,
		|	Инсталляции.ИспользуемаяОбработка КАК ИспользуемаяОбработка
		|ИЗ
		|	РегистрСведений.ИспользованиеПоставляемыхДополнительныхОтчетовИОбработокВОбластяхДанных КАК Инсталляции
		|ГДЕ
		|	Инсталляции.ПоставляемаяОбработка = &ПоставляемаяОбработка";
	Запрос = Новый Запрос(ТекстЗапроса);
	Запрос.УстановитьПараметр("ПоставляемаяОбработка", ПоставляемаяОбработка);
	Возврат Запрос.Выполнить().Выгрузить();
	
КонецФункции

// Возвращает очередь инсталляций поставляемой дополнительной обработки в области данных.
//
// Параметры:
//  ПоставляемаяОбработка - СправочникСсылка.ПоставляемыеДополнительныеОтчетыИОбработки - поставляемая обработка.
//
// Возвращаемое значение:
//  ТаблицаЗначений:
//    * ОбластьДанных - Число - число длиной 7 символов, номер области данных.
//    * ПараметрыУстановки - ХранилищеЗначения - очередь инсталляций.
//
Функция ОчередьИнсталляций(Знач ПоставляемаяОбработка)
	
	ТекстЗапроса =
		"ВЫБРАТЬ
		|	Очередь.ОбластьДанныхВспомогательныеДанные КАК ОбластьДанных,
		|	Очередь.ПараметрыИнсталляции КАК ПараметрыИнсталляции
		|ИЗ
		|	РегистрСведений.ОчередьИнсталляцииПоставляемыхДополнительныхОтчетовИОбработокВОбластиДанных КАК Очередь
		|ГДЕ
		|	Очередь.ПоставляемаяОбработка = &ПоставляемаяОбработка";
	Запрос = Новый Запрос(ТекстЗапроса);
	Запрос.УстановитьПараметр("ПоставляемаяОбработка", ПоставляемаяОбработка);
	Возврат Запрос.Выполнить().Выгрузить();
	
КонецФункции

#Область ПоставляемыеДанные

// Возвращает идентификатор вида поставляемых данных для дополнительных отчетов
// и обработок.
//
// Возвращаемое значение:
//   Строка
//
Функция ИдентификаторВидаПоставляемыхДанных()
	
	Возврат "ДОиО"; // Не локализуется
	
КонецФункции

Функция ОписаниеПоставляемойОбработки()
	
	Возврат Новый Структура("Идентификатор, Версия, Манифест, Совместимость");
	
КонецФункции

Функция РазобратьДескрипторПоставляемыхДанных(Дескриптор)
	
	ОписаниеПоставляемойОбработки = ОписаниеПоставляемойОбработки();
	
	Для Каждого ХарактеристикаПоставляемыхДанных Из Дескриптор.Properties.Property Цикл
		
		ОписаниеПоставляемойОбработки[ХарактеристикаПоставляемыхДанных.Code] = ХарактеристикаПоставляемыхДанных.Value;
		
	КонецЦикла;
	
	Возврат ОписаниеПоставляемойОбработки;
	
КонецФункции

// Контроль совместимости с текущей версией конфигурации информационной базы
Функция ПроверитьСовместимостьПоставляемойОбработки(Знач ТаблицаСовместимости)
	
	Для Каждого ДекларацияСовместимости Из ТаблицаСовместимости Цикл
		
		Если ПустаяСтрока(ДекларацияСовместимости.VersionNumber) Тогда
			
			Если ДекларацияСовместимости.ConfigarationName = Метаданные.Имя Тогда
				Возврат Истина;
			КонецЕсли;
			
		Иначе
			
			Если ДекларацияСовместимости.ConfigarationName = Метаданные.Имя И ДекларацияСовместимости.VersionNumber = Метаданные.Версия Тогда
				Возврат Истина;
			КонецЕсли;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат Ложь;
	
КонецФункции

Процедура ОбработатьПоставляемыеДополнительныеОтчетыИОбработки(Дескриптор, ПутьКФайлу)
	
	УстановитьПривилегированныйРежим(Истина);
	
	// Прочитаем характеристики экземпляра поставляемых данных
	ОписаниеПоставляемойОбработки = РазобратьДескрипторПоставляемыхДанных(Дескриптор);
	
	Чтение = Новый ЧтениеXML();
	Чтение.УстановитьСтроку(ОписаниеПоставляемойОбработки.Манифест);
	Чтение.ПерейтиКСодержимому();
	МанифестДополнительнойОбработки = ФабрикаXDTO.ПрочитатьXML(Чтение, ФабрикаXDTO.Тип(Чтение.URIПространстваИмен, Чтение.Имя));
	
	Чтение = Новый ЧтениеXML();
	Чтение.УстановитьСтроку(ОписаниеПоставляемойОбработки.Совместимость);
	Чтение.ПерейтиКСодержимому();
	ТаблицаСовместимостиXDTO = ФабрикаXDTO.ПрочитатьXML(Чтение, ФабрикаXDTO.Тип(Чтение.URIПространстваИмен, Чтение.Имя));
	ТаблицаСовместимости = ПрочитатьТаблицуСовместимости(ТаблицаСовместимостиXDTO);
	
	ЗаписьЖурналаРегистрации(НСтр("ru = 'Поставляемые дополнительные отчеты и обработки.Загрузка поставляемой обработки'", 
		ОбщегоНазначения.КодОсновногоЯзыка()),
		УровеньЖурналаРегистрации.Информация,
		,
		,
		НСтр("ru = 'Инициирована загрузка поставляемой обработки'") + Символы.ПС + Символы.ВК + ОписаниеПоставляемойОбработки.Манифест);
	
	НачатьТранзакцию();
	Попытка
		// Получим СправочникОбъект.ПоставляемыеДополнительныеОтчетыИОбработки
		СсылкаПоставляемойОбработки = Справочники.ПоставляемыеДополнительныеОтчетыИОбработки.ПолучитьСсылку(
			Новый УникальныйИдентификатор(ОписаниеПоставляемойОбработки.Идентификатор));
		Если ОбщегоНазначения.СсылкаСуществует(СсылкаПоставляемойОбработки) Тогда
			Блокировка = Новый БлокировкаДанных;
			ЭлементБлокировки = Блокировка.Добавить("Справочник.ПоставляемыеДополнительныеОтчетыИОбработки");
			ЭлементБлокировки.УстановитьЗначение("Ссылка", СсылкаПоставляемойОбработки);
			Блокировка.Заблокировать();
			
			ПоставляемаяОбработка = СсылкаПоставляемойОбработки.ПолучитьОбъект();
		Иначе
			ПоставляемаяОбработка = Справочники.ПоставляемыеДополнительныеОтчетыИОбработки.СоздатьЭлемент();
			ПоставляемаяОбработка.УстановитьСсылкуНового(СсылкаПоставляемойОбработки);
		КонецЕсли;
		
		Если ЗначениеЗаполнено(ПоставляемаяОбработка.ПричинаОтключения) Тогда
			Если ПоставляемаяОбработка.ПричинаОтключения = Перечисления.ПричиныОтключенияДополнительныхОтчетовИОбработокВМоделиСервиса.ОбновлениеВерсииКонфигурации Тогда
				ПоставляемаяОбработка.Публикация = Перечисления.ВариантыПубликацииДополнительныхОтчетовИОбработок.Используется;
				ПоставляемаяОбработка.ПричинаОтключения = Перечисления.ПричиныОтключенияДополнительныхОтчетовИОбработокВМоделиСервиса.ПустаяСсылка();
			КонецЕсли;
		Иначе
			ПоставляемаяОбработка.Публикация = Перечисления.ВариантыПубликацииДополнительныхОтчетовИОбработок.Используется;
		КонецЕсли;
		
		Если ПоставляемаяОбработка.ВерсияGUID = Новый УникальныйИдентификатор(ОписаниеПоставляемойОбработки.Версия) Тогда
			ОтменитьТранзакцию();
			Возврат;
		КонецЕсли;
			
		// Заполним СправочникОбъект.ПоставляемыеДополнительныеОтчетыИОбработки
		ВариантыОтчетовПоставляемойОбработки = Неопределено;
		ДополнительныеОтчетыИОбработкиВМоделиСервисаМанифест.ПрочитатьМанифест(
			МанифестДополнительнойОбработки, ПоставляемаяОбработка, ПоставляемаяОбработка,
			ВариантыОтчетовПоставляемойОбработки);
		
		// В качестве значения реквизита ХранилищеОбработки записывает файл поставляемых данных.
		ДвоичныеДанныеОбработки = Новый ДвоичныеДанные(ПутьКФайлу);
		ПоставляемаяОбработка.ХранилищеОбработки = Новый ХранилищеЗначения(
			ДвоичныеДанныеОбработки, Новый СжатиеДанных(9));
		
		// Таблица совместимости с версиями конфигураций
		ПоставляемаяОбработка.КонтролироватьСовместимостьСВерсиямиКонфигурации = Истина;
		ПоставляемаяОбработка.Совместимость.Очистить();
		Для Каждого ИнформацияОСовместимости Из ТаблицаСовместимости Цикл
			Если ИнформацияОСовместимости.ConfigarationName = Метаданные.Имя Тогда
				Если ПустаяСтрока(ИнформацияОСовместимости.VersionNumber) Тогда
					ПоставляемаяОбработка.КонтролироватьСовместимостьСВерсиямиКонфигурации = Ложь;
					Прервать;
				КонецЕсли;
				СтрокаТЧ = ПоставляемаяОбработка.Совместимость.Добавить();
				СтрокаТЧ.Версия = ИнформацияОСовместимости.VersionNumber;
			КонецЕсли;
		КонецЦикла;
		
		// Запишем СправочникОбъект.ПоставляемыеДополнительныеОтчетыИОбработки
		ПоставляемаяОбработка.ВерсияGUID = Новый УникальныйИдентификатор(ОписаниеПоставляемойОбработки.Версия);
		ПоставляемаяОбработка.Записать();
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ВызватьИсключение;
	КонецПопытки;
	
	ЗаписьЖурналаРегистрации(НСтр("ru = 'Поставляемые дополнительные отчеты и обработки.Загрузка поставляемой обработки завершена'",
		ОбщегоНазначения.КодОсновногоЯзыка()),
		УровеньЖурналаРегистрации.Информация,
		,
		ПоставляемаяОбработка.Ссылка,
		НСтр("ru = 'Завершена загрузка поставляемой обработки'") + Символы.ПС + Символы.ВК + ОписаниеПоставляемойОбработки.Манифест);
		
	Если Не ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.ОчередьЗаданий") Тогда
		Возврат;
	КонецЕсли;
	
	МодульОчередьЗаданий = ОбщегоНазначения.ОбщийМодуль("ОчередьЗаданий");
	// Планирование актуализации настроек используемых обработок
	ИспользуемыеОбработки = ПереченьИнсталляций(ПоставляемаяОбработка.Ссылка);
	Для Каждого ИнсталляцияОбработки Из ИспользуемыеОбработки Цикл
		
		ПараметрыМетода = Новый Массив;
		ПараметрыМетода.Добавить(ИнсталляцияОбработки.ИспользуемаяОбработка);
		
		ПараметрыЗадания = Новый Структура;
		ПараметрыЗадания.Вставить("ИмяМетода"    , "ДополнительныеОтчетыИОбработкиВМоделиСервиса.АктуализацияНастроекИспользуемойОбработки");
		ПараметрыЗадания.Вставить("Параметры"    , ПараметрыМетода);
		ПараметрыЗадания.Вставить("КоличествоПовторовПриАварийномЗавершении", 3);
		ПараметрыЗадания.Вставить("ОбластьДанных", ИнсталляцияОбработки.ОбластьДанных);
		
		МодульОчередьЗаданий.ДобавитьЗадание(ПараметрыЗадания);
		
		ЗаписьЖурналаРегистрации(НСтр("ru = 'Поставляемые дополнительные отчеты и обработки.Запланирована актуализация настроек поставляемой обработки'",
			ОбщегоНазначения.КодОсновногоЯзыка()),
			УровеньЖурналаРегистрации.Информация,
			,
			ПоставляемаяОбработка.Ссылка,
			НСтр("ru = 'Область данных:'") + ИнсталляцияОбработки.ОбластьДанных);
		
	КонецЦикла;
	
	// Планирование инсталляции поставляемой обработки в области, которые ее ожидают
	ОчередьИнсталляций = ОчередьИнсталляций(ПоставляемаяОбработка.Ссылка);
	Для Каждого ЭлементОчереди Из ОчередьИнсталляций Цикл
		
		Контекст = ЭлементОчереди.ПараметрыИнсталляции.Получить();
		
		ОписаниеИнсталляции = Новый Структура(
			"Идентификатор,Представление,Инсталляция",
			ПоставляемаяОбработка.Ссылка.УникальныйИдентификатор(),
			Контекст.Представление,
			Контекст.Инсталляция);
		
		ПараметрыМетода = Новый Массив;
		ПараметрыМетода.Добавить(ОписаниеИнсталляции);
		ПараметрыМетода.Добавить(Контекст.БыстрыйДоступ);
		ПараметрыМетода.Добавить(Контекст.Задания);
		ПараметрыМетода.Добавить(Контекст.Разделы);
		ПараметрыМетода.Добавить(Контекст.СправочникиИДокументы);
		ПараметрыМетода.Добавить(Контекст.НастройкиРасположенияКоманд);
		ПараметрыМетода.Добавить(Контекст.ВариантыДополнительногоОтчета);
		ПараметрыМетода.Добавить(Контекст.Ответственный);
		
		ПараметрыЗадания = Новый Структура;
		ПараметрыЗадания.Вставить("ИмяМетода", "ДополнительныеОтчетыИОбработкиВМоделиСервиса.УстановитьПоставляемуюОбработкуПриПолучении");
		ПараметрыЗадания.Вставить("Параметры", ПараметрыМетода);
		ПараметрыЗадания.Вставить("КоличествоПовторовПриАварийномЗавершении", 1);
		ПараметрыЗадания.Вставить("ОбластьДанных", ЭлементОчереди.ОбластьДанных);
		МодульОчередьЗаданий.ДобавитьЗадание(ПараметрыЗадания);
		
		ЗаписьЖурналаРегистрации(
			НСтр("ru = 'Поставляемые дополнительные отчеты и обработки.Запланирована отложенная установка поставляемой обработки в область данных'",
			ОбщегоНазначения.КодОсновногоЯзыка()),
			УровеньЖурналаРегистрации.Информация,
			,
			ПоставляемаяОбработка.Ссылка,
			НСтр("ru = 'Область данных:'") + ЭлементОчереди.ОбластьДанных);
		
	КонецЦикла;
	
КонецПроцедуры

#КонецОбласти

#Область ДополнительныеОтчетыИОбработки

// Возвращает Истина, если переданная ссылка на элемент справочника ДополнительныеОтчетыИОбработки
// является отчетом, а не обработкой.
//
Функция ЭтоОтчет(Знач Ссылка)
	
	Вид = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, "Вид");
	Возврат (Вид = Перечисления.ВидыДополнительныхОтчетовИОбработок.Отчет) Или (Вид = Перечисления.ВидыДополнительныхОтчетовИОбработок.ДополнительныйОтчет);
	
КонецФункции

// Процедура выполняет перезаполнение элемента справочника ДополнительныеОтчетыИОбработки
// по элементу справочника ПоставляемыеДополнительныеОтчетыИОбработки.
//
// Параметры:
//   ИспользуемаяОбработка - СправочникОбъект.ДополнительныеОтчетыИОбработки
//   ПоставляемаяОбработка - СправочникОбъект.ПоставляемыеДополнительныеОтчетыИОбработки
//
Процедура ЗаполнитьНастройкиИспользуемойОбработки(ИспользуемаяОбработка, ПоставляемаяОбработка)
	
	ЗаполнитьЗначенияСвойств(ИспользуемаяОбработка, ПоставляемаяОбработка, , "ХранилищеОбработки, Владелец, Родитель, ИспользоватьДляФормыСписка, ИспользоватьДляФормыОбъекта");
	
	КомандыИспользуемойОбработки = ИспользуемаяОбработка.Команды.Выгрузить();
	КомандыПоставляемойОбработки = ПоставляемаяОбработка.Команды.Выгрузить();
	
	// Синхронизируем команды используемой обработки по командам поставляемой обработки
	Для Каждого КомандаПоставляемойОбработки Из КомандыПоставляемойОбработки Цикл
		
		КомандаИспользуемойОбработки = КомандыИспользуемойОбработки.Найти(
			КомандаПоставляемойОбработки.Идентификатор, "Идентификатор");
		
		Если КомандаИспользуемойОбработки = Неопределено Тогда
			КомандаИспользуемойОбработки = КомандыИспользуемойОбработки.Добавить();
		КонецЕсли;
		
		ЗаполнитьЗначенияСвойств(КомандаИспользуемойОбработки, КомандаПоставляемойОбработки,
			"Идентификатор,ВариантЗапуска,Представление,ПоказыватьОповещение,Модификатор,Скрыть");
		
	КонецЦикла;
	
	// Удаляем команды используемой обработки, которые были удалены из новой версии
	// поставляемой обработки.
	УдаляемыеКоманды = Новый Массив();
	Для Каждого КомандаИспользуемойОбработки Из КомандыИспользуемойОбработки Цикл
		
		КомандаПоставляемойОбработки = КомандыПоставляемойОбработки.Найти(
			КомандаИспользуемойОбработки.Идентификатор, "Идентификатор");
		
		Если КомандаПоставляемойОбработки = Неопределено Тогда
			УдаляемыеКоманды.Добавить(КомандаИспользуемойОбработки);
		КонецЕсли;
		
	КонецЦикла;
	
	Для Каждого УдаляемаяКоманда Из УдаляемыеКоманды Цикл
		КомандыИспользуемойОбработки.Удалить(УдаляемаяКоманда);
	КонецЦикла;
	
	ИспользуемаяОбработка.Команды.Загрузить(КомандыИспользуемойОбработки);
	
	ИспользуемаяОбработка.Разрешения.Загрузить(ПоставляемаяОбработка.Разрешения.Выгрузить());
	
КонецПроцедуры

// Возвращает регистрационные данные для регистрируемой обработке по поставляемой обработке.
//
// Параметры:
//  ПоставляемаяОбработка - СправочникСсылка.ПоставляемыеДополнительныеОтчетыИОбработки.
//
// Возвращаемое значение:
//   см. ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке
//
Функция ПолучитьРегистрационныеДанные(Знач ПоставляемаяОбработка)
	
	Результат = Новый Структура("Вид, Наименование, Версия, БезопасныйРежим, Информация, ВерсияБСП, ХранилищеВариантов");
	
	УстановитьПривилегированныйРежим(Истина);
	Обработка = ПоставляемаяОбработка.ПолучитьОбъект();
	ЗаполнитьЗначенияСвойств(Результат, Обработка);
	
	// Назначение
	Назначение = Новый Массив;
	Для Каждого ЭлементНазначения Из Обработка.Назначение Цикл
		Назначение.Вставить(ЭлементНазначения.ОбъектНазначения);
	КонецЦикла;
	Результат.Вставить("Назначение", Назначение);
	
	// Команды
	Результат.Вставить("Команды", Обработка.Команды.Выгрузить(
		, "Представление, Идентификатор, Модификатор, ПоказыватьОповещение, Использование"));
	
	Возврат Результат;
	
КонецФункции

// Читает таблицу совместимости поставляемой дополнительной обработки с конфигурациями
//  и их версиями.
//
// Параметры:
//  ТаблицаСовместимости - ОбъектXDTO - ОбъектXDTO {http://www.1c.ru/1cFresh/ApplicationExtensions/Compatibility/1.0.0.1}CompatibilityList.
//
// Возвращаемое значение:
//  ТаблицаЗначений:
//    ConfigarationName - Строка - имя конфигурации,
//    VersionNumber - Строка - версия конфигурации.
//
Функция ПрочитатьТаблицуСовместимости(Знач ТаблицаСовместимости)
	
	Результат = Новый ТаблицаЗначений();
	Результат.Колонки.Добавить("ConfigarationName", Новый ОписаниеТипов("Строка"));
	Результат.Колонки.Добавить("VersionNumber", Новый ОписаниеТипов("Строка"));
	
	Для Каждого CompatibilityObject Из ТаблицаСовместимости.CompatibilityObjects Цикл
		
		Строка = Результат.Добавить();
		ЗаполнитьЗначенияСвойств(Строка, CompatibilityObject);
		
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

#КонецОбласти

#Область СпецификаРаботыСДополнительнымиОтчетамиИОбработкамиВМоделиСервиса

// Процедура предназначена для синхронизации значений констант, регулирующих
//  использование дополнительных отчетов и обработок в модели сервиса. Процедура
//  должна вызываться при любом изменении любой из констант, регулирующих
//  использование дополнительных отчетов и обработок.
//
// Параметры:
//  Константа - Строка - имя измененной константы, как оно задано в метаданных,
//  Значение - Булево - новое значение измененной константы.
//
Процедура СинхронизацияЗначенийРегулирующихКонстант(Знач Константа, Знач Значение) Экспорт
	
	СостояниеИспользования = Ложь;
	
	РегулирующиеКонстанты = ДополнительныеОтчетыИОбработкиВМоделиСервисаПовтИсп.РегулирующиеКонстанты();
	
	Для Каждого РегулирующаяКонстанта Из РегулирующиеКонстанты Цикл
		
		Если РегулирующаяКонстанта = Константа Тогда
			ЗначениеКонстанты = Значение;
		Иначе
			ЗначениеКонстанты = Константы[РегулирующаяКонстанта].Получить();
		КонецЕсли;
		
		Если ЗначениеКонстанты Тогда
			СостояниеИспользования = Истина;
		КонецЕсли;
		
	КонецЦикла;
	
	Константы.ИспользоватьДополнительныеОтчетыИОбработки.Установить(СостояниеИспользования);
	
КонецПроцедуры

// Вызывается при проверке возможности выполнения дополнительного отчета или обработки.
//
Процедура ПроверитьВозможностьВыполнения(Ссылка)
	
	Если Не ОбщегоНазначения.РазделениеВключено() Тогда
		Возврат;
	КонецЕсли;
		
	УстановитьПривилегированныйРежим(Истина);
	Если Не ЭтоПоставляемаяОбработка(Ссылка) Тогда
		Если Не ПолучитьФункциональнуюОпцию("НезависимоеИспользованиеДополнительныхОтчетовИОбработокВМоделиСервиса") Тогда
			ВызватьИсключение НСтр("ru = 'Этот дополнительный отчет или обработка не может быть использован в сервисе.'");
		КонецЕсли;
		Возврат;
	КонецЕсли;
			
	ПроверкаВозможностиВыполненияПоставляемойОбработки(Ссылка);
	
КонецПроцедуры

// Процедура вызывается для проверки возможности выполнения кода дополнительной обработки
//  в информационной базе.
//
Процедура ПроверкаВозможностиВыполненияПоставляемойОбработки(Знач ИспользуемаяОбработка)
	
	ПараметрыПубликацииИспользуемойОбработки = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(ИспользуемаяОбработка, "Публикация, Версия");
	Если ПараметрыПубликацииИспользуемойОбработки.Публикация = Перечисления.ВариантыПубликацииДополнительныхОтчетовИОбработок.Отключена Тогда
		ВызватьИсключение НСтр(
			"ru = 'Использование дополнительной обработки запрещено. Обратитесь за помощью к пользователю, обладающего правами администратора в приложении.'");
	КонецЕсли;
	
	ОписанияПричинБлокировки = ДополнительныеОтчетыИОбработкиВМоделиСервисаПовтИсп.РасширенныеОписанияПричинБлокировки();
	
	УстановитьПривилегированныйРежим(Истина);
	ПоставляемаяОбработка = ПоставляемаяОбработка(ИспользуемаяОбработка);
	Если Не ЗначениеЗаполнено(ПоставляемаяОбработка) Тогда
		Возврат;
	КонецЕсли;
		
	ПараметрыПубликацииПоставляемойОбработки = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(ПоставляемаяОбработка, "Публикация, ПричинаОтключения, Версия");
	
	// Проверка публикации поставляемой обработки
	Если ПараметрыПубликацииПоставляемойОбработки.Публикация = Перечисления.ВариантыПубликацииДополнительныхОтчетовИОбработок.Отключена Тогда
		ВызватьИсключение ОписанияПричинБлокировки[ПараметрыПубликацииПоставляемойОбработки.ПричинаОтключения];
	КонецЕсли;
	
	// Проверка на выполнение обновления версии обработки
	Если ПараметрыПубликацииИспользуемойОбработки.Версия <> ПараметрыПубликацииПоставляемойОбработки.Версия Тогда
		ВызватьИсключение НСтр(
			"ru = 'Использование дополнительной обработки временно недоступно. Повторите попытку через несколько минут. Приносим извинения на доставленные неудобства.'");
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиУсловныхВызовов

Процедура ПриСериализацииВладельцаРазрешенийНаИспользованиеВнешнихРесурсов(Знач Владелец, СтандартнаяОбработка, Результат) Экспорт
	
	Если ТипЗнч(Владелец) = Тип("СправочникСсылка.ДополнительныеОтчетыИОбработки")
		И ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
		
		СтандартнаяОбработка = Ложь;
		
		Результат = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("http://www.1c.ru/1cFresh/Application/Permissions/Management/1.0.0.1", "PermissionsOwnerExternalModule"));
		Результат.Type = "ApplicationExtension";
		Результат.UUID = Владелец.УникальныйИдентификатор();
		
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#КонецОбласти
